home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / clients / xclipboa / xclipboa.c < prev    next >
C/C++ Source or Header  |  1994-08-12  |  19KB  |  724 lines

  1. /*
  2.  * $XConsortium: xclipboard.c,v 1.25 91/07/22 15:53:36 converse Exp $
  3.  *
  4.  * Copyright 1989 Massachusetts Institute of Technology
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software and its
  7.  * documentation for any purpose and without fee is hereby granted, provided
  8.  * that the above copyright notice appear in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the name of M.I.T. not be used in advertising
  11.  * or publicity pertaining to distribution of the software without specific,
  12.  * written prior permission.  M.I.T. makes no representations about the
  13.  * suitability of this software for any purpose.  It is provided "as is"
  14.  * without express or implied warranty.
  15.  *
  16.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  17.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  18.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
  21.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  *
  23.  * Author:  Ralph Swick, DEC/Project Athena
  24.  * Updated for R4:  Chris D. Peterson,  MIT X Consortium.
  25.  * Reauthored by: Keith Packard, MIT X Consortium.
  26.  */
  27.  
  28. #include <stdio.h>
  29. #ifdef MSDOS
  30. #include "X11/Intrinsc.h"      /* QDK 05/12/1994 10:32am. */
  31. #else
  32. #include "X11/Intrinsic.h"
  33. #endif
  34. #include <X11/StringDefs.h>
  35. #include <X11/Xatom.h>
  36.  
  37. #include <X11/Xmu/Atoms.h>
  38. #include <X11/Xmu/StdSel.h>
  39.  
  40. #include <X11/Shell.h>
  41. #include <X11/Xaw/Form.h>
  42. #include <X11/Xaw/Label.h>
  43. #include <X11/Xaw/Command.h>
  44. #include <X11/Xaw/AsciiText.h>
  45. #include <X11/Xaw/Dialog.h>
  46. #include <X11/Xaw/Cardinals.h>
  47. #include <X11/Xfuncs.h>
  48.  
  49. #define Command commandWidgetClass
  50. #define Label    labelWidgetClass
  51. #define Text    asciiTextWidgetClass
  52.  
  53. #define INFINITY 10000000    /* pretty big, huh? */
  54.  
  55. typedef struct _Clip {
  56.     struct _Clip    *next, *prev;
  57.     char        *clip;
  58.     char        *filename;
  59.     int            avail;
  60. } ClipRec, *ClipPtr;
  61.  
  62. extern char *malloc ();
  63.  
  64. static Atom wm_delete_window;
  65. static Atom wm_protocols;
  66.  
  67. static long TextLength (w)
  68.     Widget  w;
  69. {
  70.     return XawTextSourceScan (XawTextGetSource (w),
  71.                   (XawTextPosition) 0,
  72.                    XawstAll, XawsdRight, 1, TRUE);
  73. }
  74.  
  75. SaveClip (w, clip)
  76.     Widget  w;
  77.     ClipPtr clip;
  78. {
  79.     Arg        args[1];
  80.     char    *data;
  81.     int        len;
  82.     Widget  source;
  83.  
  84.     source = XawTextGetSource (w);
  85.     XtSetArg (args[0], XtNstring, &data);
  86.     XtGetValues (source, args, 1);
  87.     len = strlen (data);
  88.     if (len >= clip->avail)
  89.     {
  90.     if (clip->clip)
  91.         free (clip->clip);
  92.     clip->clip = malloc (len + 1);
  93.     if (!clip->clip)
  94.         clip->avail = 0;
  95.     else
  96.         clip->avail = len + 1;
  97.     }
  98.     if (clip->avail)
  99.     {
  100.     strcpy (clip->clip, data);
  101.     }
  102. }
  103.  
  104. RestoreClip (w, clip)
  105.     Widget  w;
  106.     ClipPtr clip;
  107. {
  108.     Arg        args[1];
  109.     Widget  source;
  110.  
  111.     source = XawTextGetSource (w);
  112.     XtSetArg (args[0], XtNstring, clip->clip);
  113.     XtSetValues (source, args, 1);
  114. }
  115.  
  116. /*ARGSUSED*/
  117. ClipPtr 
  118. NewClip (w, old)
  119.     Widget  w;
  120.     ClipPtr old;
  121. {
  122.     ClipPtr newClip;
  123.  
  124.     newClip = (ClipPtr) malloc (sizeof (ClipRec));
  125.     if (!newClip)
  126.     return newClip;
  127.     newClip->clip = 0;
  128.     newClip->avail = 0;
  129.     newClip->prev = old;
  130.     newClip->next = NULL;
  131.     newClip->filename = NULL;
  132.     if (old)
  133.     {
  134.     newClip->next = old->next;
  135.     old->next = newClip;
  136.     }
  137.     return newClip;
  138. }
  139.  
  140. /*ARGSUSED*/
  141. DeleteClip (w, clip)
  142.     Widget  w;
  143.     ClipPtr clip;
  144. {
  145.     if (clip->prev)
  146.     clip->prev->next = clip->next;
  147.     if (clip->next)
  148.     clip->next->prev = clip->prev;
  149.     if (clip->clip)
  150.     free (clip->clip);
  151.     free ((char *) clip);
  152. }
  153.  
  154. static ClipPtr    currentClip;
  155. static Widget    top;
  156. static Widget    text, nextButton, prevButton, indexLabel;
  157. static Widget    fileDialog, fileDialogShell;
  158. static Widget    failDialog, failDialogShell;
  159.  
  160. static int
  161. IndexCurrentClip ()
  162. {
  163.     int    i = 0;
  164.     ClipPtr clip;
  165.  
  166.     for (clip = currentClip; clip; clip = clip->prev)
  167.     i++;
  168.     return i;
  169. }
  170.  
  171. static void
  172. set_button_state ()
  173. {
  174.     Boolean prevvalid, nextvalid;
  175.     Arg arg;
  176.     char labelString[10];
  177.  
  178.     prevvalid = currentClip->prev != NULL;
  179.     nextvalid = currentClip->next != NULL;
  180.     XtSetArg (arg, XtNsensitive, prevvalid);
  181.     XtSetValues (prevButton, &arg, ONE);
  182.     XtSetArg (arg, XtNsensitive, nextvalid);
  183.     XtSetValues (nextButton, &arg, ONE);
  184.     sprintf (labelString, "%d", IndexCurrentClip ());
  185.     XtSetArg (arg, XtNlabel, labelString);
  186.     XtSetValues (indexLabel, &arg, ONE);
  187. }
  188.  
  189. /* ARGSUSED */
  190. static void
  191. NextCurrentClip (w, ev, parms, np)
  192.     Widget    w;
  193.     XEvent    *ev;
  194.     String    *parms;
  195.     Cardinal    *np;
  196. {
  197.     if (currentClip->next)
  198.     {
  199.     SaveClip (text, currentClip);
  200.     currentClip = currentClip->next;
  201.     RestoreClip (text, currentClip);
  202.     set_button_state ();
  203.     }
  204. }
  205.  
  206. /* ARGSUSED */
  207. static void
  208. PrevCurrentClip (w, ev, parms, np)
  209.     Widget    w;
  210.     XEvent    *ev;
  211.     String    *parms;
  212.     Cardinal    *np;
  213. {
  214.     if (currentClip->prev)
  215.     {
  216.     SaveClip (text, currentClip);
  217.     currentClip = currentClip->prev;
  218.     RestoreClip (text, currentClip);
  219.     set_button_state ();
  220.     }
  221. }
  222.  
  223. /* ARGSUSED */
  224. static void
  225. DeleteCurrentClip (w, ev, parms, np)
  226.     Widget    w;
  227.     XEvent    *ev;
  228.     String    *parms;
  229.     Cardinal    *np;
  230. {
  231.     ClipPtr newCurrent;
  232.  
  233.     if (currentClip->prev)
  234.     newCurrent = currentClip->prev;
  235.     else
  236.     newCurrent = currentClip->next;
  237.     if (newCurrent)
  238.     {
  239.     DeleteClip (text, currentClip);
  240.     currentClip = newCurrent;
  241.     RestoreClip (text, currentClip);
  242.     }
  243.     else
  244.     EraseTextWidget ();
  245.     set_button_state ();
  246. }
  247.  
  248. /* ARGSUSED */
  249. static void
  250. Quit (w, ev, parms, np)
  251.     Widget    w;
  252.     XEvent    *ev;
  253.     String    *parms;
  254.     Cardinal    *np;
  255. {
  256.     XtCloseDisplay  (XtDisplay (text));
  257.     exit (0);
  258. }
  259.  
  260. static void
  261. CenterWidgetAtPoint (w, x, y)
  262.     Widget  w;
  263.     int        x, y;
  264. {
  265.     Arg    args[2];
  266.     Dimension    width, height;
  267.  
  268.     XtSetArg(args[0], XtNwidth, &width);
  269.     XtSetArg(args[1], XtNheight, &height);
  270.     XtGetValues (w, args, 2);
  271.     x = x - (int) width / 2;
  272.     y = y - (int) height / 2;
  273.     if (x < 0)
  274.     x = 0;
  275.     else {
  276.     int scr_width = WidthOfScreen (XtScreen(w));
  277.     if (x + (int)width > scr_width)
  278.         x = scr_width - width;
  279.     }
  280.     if (y < 0)
  281.     y = 0;
  282.     else {
  283.     int scr_height = HeightOfScreen (XtScreen(w));
  284.     if (y + (int)height > scr_height)
  285.         y = scr_height - height;
  286.     }
  287.     XtSetArg(args[0], XtNx, x);
  288.     XtSetArg(args[1], XtNy, y);
  289.     XtSetValues (w, args, 2);
  290. }
  291.  
  292. static void
  293. CenterWidgetOnEvent (w, e)
  294.     Widget  w;
  295.     XEvent  *e;
  296. {
  297.     CenterWidgetAtPoint (w, e->xbutton.x_root, e->xbutton.y_root);
  298. }
  299.  
  300. static void
  301. CenterWidgetOnWidget (w, wT)
  302.     Widget  w, wT;
  303. {
  304.     Position    rootX, rootY;
  305.     Dimension    width, height;
  306.     Arg        args[2];
  307.  
  308.     XtSetArg (args[0], XtNwidth, &width);
  309.     XtSetArg (args[1], XtNheight, &height);
  310.     XtGetValues (wT, args, 2);
  311.     XtTranslateCoords (wT, (Position) width/2, (Position) height/2, &rootX, &rootY);
  312.     CenterWidgetAtPoint (w, (int) rootX, (int) rootY);
  313. }
  314.  
  315. /*ARGSUSED*/
  316. static void
  317. SaveToFile (w, e, argv, argc)
  318.     Widget  w;
  319.     XEvent  *e;
  320.     String  *argv;
  321.     Cardinal        *argc;
  322. {
  323.     Arg        args[1];
  324.     char    *filename;
  325.  
  326.     filename = "clipboard";
  327.     if (currentClip->filename)
  328.     filename = currentClip->filename;
  329.     XtSetArg(args[0], XtNvalue, filename);
  330.     XtSetValues (fileDialog, args, 1);
  331.     CenterWidgetOnEvent (fileDialogShell, e);
  332.     XtPopup (fileDialogShell, XtGrabNone);
  333. }
  334.  
  335. /*ARGSUSED*/
  336. static void
  337. AcceptSaveFile (w, e, argv, argc)
  338.     Widget  w;
  339.     XEvent  *e;
  340.     String  *argv;
  341.     Cardinal    *argc;
  342. {
  343.     char    *filename;
  344.     Boolean success;
  345.     Arg        args[1];
  346.  
  347.     filename = XawDialogGetValueString (fileDialog);
  348.     success = XawAsciiSaveAsFile (XawTextGetSource (text), filename);
  349.     XtPopdown (fileDialogShell);
  350.     if (!success)
  351.     {
  352.     char    failMessage[1024];
  353.  
  354.     sprintf (failMessage, "Can't open file \"%s\"", filename);
  355.     XtSetArg (args[0], XtNlabel, failMessage);
  356.     XtSetValues (failDialog, args, 1);
  357.     CenterWidgetOnEvent (failDialogShell, e);
  358.     XtPopup (failDialogShell, XtGrabNone);
  359.     }
  360.     else
  361.     {
  362.     if (currentClip->filename)
  363.         free (currentClip->filename);
  364.     currentClip->filename = malloc (strlen (filename) + 1);
  365.     if (currentClip->filename)
  366.         strcpy (currentClip->filename, filename);
  367.     }
  368. }
  369.  
  370. /* ARGSUSED */
  371. static void
  372. CancelSaveFile (w, ev, parms, np)
  373.     Widget    w;
  374.     XEvent    *ev;
  375.     String    *parms;
  376.     Cardinal    *np;
  377. {
  378.     XtPopdown (fileDialogShell);
  379. }
  380.  
  381. /* ARGSUSED */
  382. static void
  383. FailContinue (w, ev, parms, np)
  384.     Widget    w;
  385.     XEvent    *ev;
  386.     String    *parms;
  387.     Cardinal    *np;
  388. {
  389.     XtPopdown (failDialogShell);
  390. }
  391.  
  392. /*ARGSUSED*/
  393. static void WMProtocols(w, ev, params, n)
  394.     Widget    w;
  395.     XEvent    *ev;
  396.     String    *params;
  397.     Cardinal    *n;
  398. {
  399.     if (ev->type == ClientMessage &&
  400.     ev->xclient.message_type == wm_protocols &&
  401.     ev->xclient.data.l[0] == wm_delete_window) {
  402.     while (w && !XtIsShell(w))
  403.         w = XtParent(w);
  404.     if (w == top)
  405.         Quit(w, ev, params, n);
  406.     else if (w == fileDialogShell)
  407.         CancelSaveFile(w, ev, params, n);
  408.     else if (w == failDialogShell)
  409.         FailContinue(w, ev, params, n);
  410.     }
  411. }
  412.  
  413. /* ARGUSED */
  414. static void
  415. NewCurrentClip (w, ev, parms, np)
  416.     Widget    w;
  417.     XEvent    *ev;
  418.     String    *parms;
  419.     Cardinal    *np;
  420. {
  421.     NewCurrentClipContents ("", 0);
  422. }
  423.  
  424. NewCurrentClipContents (data, len)
  425.     char    *data;
  426.     int        len;
  427. {
  428.     XawTextBlock textBlock;
  429.  
  430.     SaveClip (text, currentClip);
  431.  
  432.     /* append new clips at the end */
  433.     while (currentClip && currentClip->next)
  434.     currentClip = currentClip->next;
  435.     /* any trailing clips with no text get overwritten */
  436.     if (strlen (currentClip->clip) != 0)
  437.     currentClip = NewClip (text, currentClip);
  438.     
  439.     textBlock.ptr = data;
  440.     textBlock.firstPos = 0;
  441.     textBlock.length = len;
  442.     textBlock.format = FMT8BIT;
  443.     if (XawTextReplace(text, 0, TextLength (text), &textBlock))
  444.     XBell( XtDisplay(text), 0);
  445.     set_button_state ();
  446. }
  447.  
  448. EraseTextWidget ()
  449. {
  450.     XawTextBlock block;
  451.  
  452.     block.ptr = "";
  453.     block.length = 0;
  454.     block.firstPos = 0;
  455.     block.format = FMT8BIT;
  456.  
  457.     XawTextReplace(text, 0, INFINITY, &block);
  458.     /* If this fails, too bad. */
  459. }
  460.  
  461.  
  462. XtActionsRec xclipboard_actions[] = {
  463.     "NewClip", NewCurrentClip,
  464.     "NextClip",    NextCurrentClip,
  465.     "PrevClip", PrevCurrentClip,
  466.     "DeleteClip", DeleteCurrentClip,
  467.     "Save", SaveToFile,
  468.     "AcceptSave", AcceptSaveFile,
  469.     "CancelSave", CancelSaveFile,
  470.     "FailContinue", FailContinue,
  471.     "Quit", Quit,
  472.     "WMProtocols", WMProtocols
  473. };
  474.  
  475. static XrmOptionDescRec table[] = {
  476.     {"-w",        "wrap",        XrmoptionNoArg,  "on"},
  477. /*    {"-nw",        "wrap",        XrmoptionNoArg,  "False"} */
  478. };
  479.  
  480. static void    LoseSelection ();
  481. static void    InsertClipboard ();
  482. static Boolean    ConvertSelection();
  483. static Atom    ManagerAtom, ClipboardAtom;
  484.  
  485. /*ARGSUSED*/
  486. static void 
  487. InsertClipboard(w, client_data, selection, type, value, length, format)
  488. Widget w;
  489. XtPointer client_data;
  490. Atom *selection, *type;
  491. XtPointer value;
  492. unsigned long *length;
  493. int *format;
  494. {
  495.     if (*type != XT_CONVERT_FAIL)
  496.     NewCurrentClipContents ((char *) value, *length);
  497.     else
  498.     {
  499.     Arg arg;
  500.     XtSetArg (arg, XtNlabel, "CLIPBOARD selection conversion failed");
  501.     XtSetValues (failDialog, &arg, 1);
  502.     CenterWidgetOnWidget (failDialogShell, text);
  503.     XtPopup (failDialogShell, XtGrabNone);
  504.     XBell( XtDisplay(w), 0 );
  505.     }
  506.     
  507.     XtOwnSelection(top, ClipboardAtom, CurrentTime,
  508.            ConvertSelection, LoseSelection, NULL);
  509.     XFree(value);
  510. }
  511.  
  512. static Boolean ConvertSelection(w, selection, target,
  513.                 type, value, length, format)
  514.     Widget w;
  515.     Atom *selection, *target, *type;
  516.     XtPointer *value;
  517.     unsigned long *length;
  518.     int *format;
  519. {
  520.     Display* d = XtDisplay(w);
  521.     XSelectionRequestEvent* req =
  522.     XtGetSelectionRequest(w, *selection, (XtRequestId)NULL);
  523.  
  524.     if (*target == XA_TARGETS(d)) {
  525.     Atom* targetP;
  526.     Atom* std_targets;
  527.     unsigned long std_length;
  528.     XmuConvertStandardSelection(w, req->time, selection, target, type,
  529.                   (caddr_t*)&std_targets, &std_length, format);
  530.     *value = XtMalloc(sizeof(Atom)*(std_length + 5));
  531.     targetP = *(Atom**)value;
  532.     *targetP++ = XA_STRING;
  533.     *targetP++ = XA_TEXT(d);
  534.     *targetP++ = XA_LENGTH(d);
  535.     *targetP++ = XA_LIST_LENGTH(d);
  536.     *targetP++ = XA_CHARACTER_POSITION(d);
  537.     *length = std_length + (targetP - (*(Atom **) value));
  538.     bcopy((char*)std_targets, (char*)targetP, sizeof(Atom)*std_length);
  539.     XtFree((char*)std_targets);
  540.     *type = XA_ATOM;
  541.     *format = 32;
  542.     return True;
  543.     }
  544.  
  545.     if (*target == XA_LIST_LENGTH(d) ||
  546.     *target == XA_LENGTH(d))
  547.     {
  548.         long * temp;
  549.         
  550.         temp = (long *) XtMalloc(sizeof(long));
  551.         if (*target == XA_LIST_LENGTH(d))
  552.             *temp = 1L;
  553.         else            /* *target == XA_LENGTH(d) */
  554.             *temp = (long) TextLength (text);
  555.         
  556.         *value = (caddr_t) temp;
  557.         *type = XA_INTEGER;
  558.         *length = 1L;
  559.         *format = 32;
  560.         return True;
  561.     }
  562.     
  563.     if (*target == XA_CHARACTER_POSITION(d))
  564.     {
  565.         long * temp;
  566.         
  567.         temp = (long *) XtMalloc(2 * sizeof(long));
  568.         temp[0] = (long) 0;
  569.         temp[1] = TextLength (text);
  570.         *value = (caddr_t) temp;
  571.         *type = XA_SPAN(d);
  572.         *length = 2L;
  573.         *format = 32;
  574.         return True;
  575.     }
  576.     
  577.     if (*target == XA_STRING ||
  578.       *target == XA_TEXT(d) ||
  579.       *target == XA_COMPOUND_TEXT(d))
  580.     {
  581.     extern char *_XawTextGetSTRING();
  582.         if (*target == XA_COMPOUND_TEXT(d))
  583.         *type = *target;
  584.         else
  585.         *type = XA_STRING;
  586.     *length = TextLength (text);
  587.         *value = _XawTextGetSTRING((TextWidget) text, 0, *length);
  588.         *format = 8;
  589.         return True;
  590.     }
  591.     
  592.     if (XmuConvertStandardSelection(w, req->time, selection, target, type,
  593.                     (caddr_t *)value, length, format))
  594.     return True;
  595.  
  596.     return False;
  597. }
  598.  
  599. static void LoseSelection(w, selection)
  600.     Widget w;
  601.     Atom *selection;
  602. {
  603.     XtGetSelectionValue(w, *selection, XA_STRING, InsertClipboard,
  604.             NULL, CurrentTime);
  605. }
  606.  
  607. /*ARGSUSED*/
  608. static Boolean RefuseSelection(w, selection, target,
  609.                    type, value, length, format)
  610.     Widget w;
  611.     Atom *selection, *target, *type;
  612.     XtPointer *value;
  613.     unsigned long *length;
  614.     int *format;
  615. {
  616.     return False;
  617. }
  618.  
  619. /*ARGSUSED*/
  620. static void LoseManager(w, selection)
  621.     Widget w;
  622.     Atom *selection;
  623. {
  624.     XtError("another clipboard has taken over control\n");
  625. }
  626.  
  627. typedef struct {
  628.   Boolean wrap;
  629. } ResourceData, *ResourceDataPtr;
  630.  
  631. static ResourceData userOptions;
  632.  
  633. #define Offset(field) XtOffsetOf(ResourceData, field)
  634.  
  635. XtResource resources[] = {
  636.   {"wrap", "Wrap", XtRBoolean, sizeof(Boolean),
  637.      Offset(wrap), XtRImmediate, (XtPointer)False}
  638. };
  639.  
  640. #undef Offset
  641.  
  642. void
  643. main(argc, argv)
  644. int argc;
  645. char **argv;
  646. {
  647.     Arg args[4];
  648.     Cardinal n;
  649.     XtAppContext xtcontext;
  650.     Widget parent, quit, delete, new, save;
  651.  
  652.     top = XtAppInitialize( &xtcontext, "XClipboard", table, XtNumber(table),
  653.               &argc, argv, NULL, NULL, 0);
  654.  
  655.     XtGetApplicationResources(top, (XtPointer)&userOptions, resources, 
  656.                   XtNumber(resources), NULL, 0);
  657.  
  658.     XtAppAddActions (xtcontext,
  659.              xclipboard_actions, XtNumber (xclipboard_actions));
  660.     /* CLIPBOARD_MANAGER is a non-standard mechanism */
  661.     ManagerAtom = XInternAtom(XtDisplay(top), "CLIPBOARD_MANAGER", False);
  662.     ClipboardAtom = XA_CLIPBOARD(XtDisplay(top));
  663.     if (XGetSelectionOwner(XtDisplay(top), ManagerAtom))
  664.     XtError("another clipboard is already running\n");
  665.  
  666.     parent = XtCreateManagedWidget("form", formWidgetClass, top, NULL, ZERO);
  667.     quit = XtCreateManagedWidget("quit", Command, parent, NULL, ZERO);
  668.     delete = XtCreateManagedWidget("delete", Command, parent, NULL, ZERO);
  669.     new = XtCreateManagedWidget("new", Command, parent, NULL, ZERO);
  670.     save = XtCreateManagedWidget("save", Command, parent, NULL, ZERO);
  671.     nextButton = XtCreateManagedWidget("next", Command, parent, NULL, ZERO);
  672.     prevButton = XtCreateManagedWidget("prev", Command, parent, NULL, ZERO);
  673.     indexLabel = XtCreateManagedWidget("index", Label, parent, NULL, ZERO);
  674.  
  675.     n=0;
  676.     XtSetArg(args[n], XtNtype, XawAsciiString); n++;
  677.     XtSetArg(args[n], XtNeditType, XawtextEdit); n++;
  678.     if (userOptions.wrap) {
  679.     XtSetArg(args[n], XtNwrap, XawtextWrapWord); n++;
  680.     XtSetArg(args[n], XtNscrollHorizontal, False); n++;
  681.     }
  682.  
  683.     text = XtCreateManagedWidget( "text", Text, parent, args, n);
  684.     
  685.     currentClip = NewClip (text, (ClipPtr) 0);
  686.  
  687.     set_button_state ();
  688.  
  689.     fileDialogShell = XtCreatePopupShell("fileDialogShell",
  690.                      transientShellWidgetClass,
  691.                      top, NULL, ZERO);
  692.     fileDialog = XtCreateManagedWidget ("fileDialog", dialogWidgetClass,
  693.                     fileDialogShell, NULL, ZERO);
  694.     XawDialogAddButton(fileDialog, "accept", NULL, NULL);
  695.     XawDialogAddButton(fileDialog, "cancel", NULL, NULL);
  696.  
  697.     failDialogShell = XtCreatePopupShell("failDialogShell",
  698.                      transientShellWidgetClass,
  699.                      top, NULL, ZERO);
  700.     failDialog = XtCreateManagedWidget ("failDialog", dialogWidgetClass,
  701.                     failDialogShell, NULL, ZERO);
  702.     XawDialogAddButton (failDialog, "continue", NULL, NULL);
  703.  
  704.     XtRealizeWidget(top);
  705.     XtRealizeWidget(fileDialogShell);
  706.     XtRealizeWidget(failDialogShell);
  707.     XtOwnSelection(top, ManagerAtom, CurrentTime,
  708.            RefuseSelection, LoseManager, NULL);
  709.     if (XGetSelectionOwner (XtDisplay(top), ClipboardAtom)) {
  710.     LoseSelection (top, &ClipboardAtom);
  711.     } else {
  712.         XtOwnSelection(top, ClipboardAtom, CurrentTime,
  713.                ConvertSelection, LoseSelection, NULL);
  714.     }
  715.     wm_delete_window = XInternAtom(XtDisplay(top), "WM_DELETE_WINDOW", False);
  716.     wm_protocols = XInternAtom(XtDisplay(top), "WM_PROTOCOLS", False);
  717.     (void) XSetWMProtocols(XtDisplay(top), XtWindow(top), &wm_delete_window,1);
  718.     (void) XSetWMProtocols(XtDisplay(top), XtWindow(fileDialogShell),
  719.                &wm_delete_window,1);
  720.     (void) XSetWMProtocols(XtDisplay(top), XtWindow(failDialogShell),
  721.                &wm_delete_window,1);
  722.     XtAppMainLoop(xtcontext);
  723. }
  724.